﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Domain.DomainLayer;
namespace HA.Data
{
    [Serializable]
   public class BCDrain:BCType,ICloneable
    {
        public BCDrain()
            : base()
        {
            this._isPtType = true;

            this._isLnType = true;

            this._isPyType = true;


            //根据应力期数量，添加默认值




            //this._multiConductance = new List<double>();
            
           
            //this._multiStartElevation = new List<double>();

            

            //this._multiEndElevation = new List<double>();


            //this._multiElevation = new List<double>();



            //for (int i = 0; i < this.NPeriods; i++)
            //{
            //    this._multiConductance.Add (0);
            //    this._multiStartElevation.Add(0);
            //    this._multiElevation.Add(0);
            //    this._multiEndElevation.Add(0);
                
            //}


        }
        //double _elevation;
        BCDateDataCollection _multiElevation = new BCDateDataCollection();
        public double Elevation
        {
            get
            {
                return this._multiElevation.IsDataConst?_multiElevation.ConstData: this._multiElevation.BCDatas[0].Value;
            }
            set
            {
                if (this._multiElevation.IsDataConst)
                    this._multiElevation.ConstData = value;
                else
                    this._multiElevation.BCDatas[0].Value = value;
            }
        }

        public BCDateDataCollection MultiElevation
        {
            get { return _multiElevation; }
            set { this._multiElevation = value; }
        }

        //double _conductance;

        public double FirstConductance
        {
            get
            {
                return this._multiConductance.IsDataConst ? _multiConductance.ConstData : this._multiConductance.BCDatas[0].Value;
            }
            set
            {
                if (this._multiConductance.IsDataConst)
                    this._multiConductance.ConstData = value;
                else
                    this._multiConductance.BCDatas[0].Value = value;
            }

        }


        BCDateDataCollection _multiConductance = new BCDateDataCollection();

        public BCDateDataCollection MultiConductance
        {
            get { return _multiConductance; }
            set { _multiConductance = value; }
        }



        BCDateDataCollection _multiStartElevation = new BCDateDataCollection();

        public BCDateDataCollection MultiStartElevation
        {
            get { return _multiStartElevation; }
            set { _multiStartElevation = value; }
        }

        BCDateDataCollection _multiEndElevation = new BCDateDataCollection();

        public BCDateDataCollection MultiEndElevation
        {
            get { return _multiEndElevation; }
            set { _multiEndElevation = value; }
        }



        //double _endElevation;

        public double EndElevation
        {
            get { return this._multiEndElevation.IsDataConst ? _multiEndElevation.ConstData : this._multiEndElevation.BCDatas[0].Value; }
            set
            {
                if (this._multiEndElevation.IsDataConst)
                    this._multiEndElevation.ConstData = value;
                else
                    this._multiEndElevation.BCDatas[0].Value = value;
            }
        }


        //private double _startElevation;

        public double StartElevation
        {
            get { return this._multiStartElevation.IsDataConst ? _multiStartElevation.ConstData : this._multiStartElevation.BCDatas[0].Value; }
            set
            {
                if (this._multiStartElevation.IsDataConst)
                    this._multiStartElevation.ConstData = value;
                else
                    this._multiStartElevation.BCDatas[0].Value = value;
            }
        }

        //public override void OnNPeriodsChanged()
        //{
        //    base.OnNPeriodsChanged();

        //    //取得之前数据的个数
        //    int n = this.MultiConductance.Count;



        //    //开始更新数据


        //    if (n < this.NPeriods)
        //    {
        //        int nSub = this.NPeriods - n;

        //        for (int i = 0; i < nSub; i++)
        //        {
        //            this.MultiConductance.Add(0);
        //            this.MultiElevation.Add(0);
        //            this.MultiEndElevation.Add(0);
        //            this.MultiStartElevation.Add(0);
        //        }
        //    }

        //    else
        //    {
        //        int nSub = n - this.NPeriods;
        //        this.MultiConductance.RemoveRange(this.NPeriods, nSub);
        //        this.MultiElevation.RemoveRange(this.NPeriods,nSub);
        //        this.MultiEndElevation.RemoveRange(this.NPeriods, nSub);
        //        this.MultiStartElevation.RemoveRange(this.NPeriods, nSub);
        //    }


        //    //this.NPeriods;

        //}


        public object Clone()
        {
            //throw new NotImplementedException();
            BCDrain bcdr = (BCDrain)this.MemberwiseClone();

            bcdr._multiConductance = (BCDateDataCollection)this._multiConductance.Clone();


            bcdr._multiElevation = (BCDateDataCollection)this._multiElevation.Clone();


            bcdr._multiEndElevation = (BCDateDataCollection)this._multiEndElevation.Clone();


            bcdr._multiStartElevation = (BCDateDataCollection)this._multiStartElevation.Clone();


            return bcdr;
        }

        public override void MapToModflow(List<double> stressPeriods, List<ValueResult> ijkList, ModFlow.Domain.DomainLayer.ModFlowData mf, FeatureObject owner)
        {
            if (ijkList.Count <= 0) return;
            int k = ijkList[0].K;

            List<int> indice = new List<int>();

            List<Drain> Drains = new List<Drain>();


            double TotalValue = owner.GetTotalLValue();

            //double currentLength = 0;

            foreach (ValueResult  item in ijkList)
            {
                //if (item.K != k)
                //{
                //    k = item.K;
                //    currentLength = 0;
                //}
                indice.Add(mf.GridData.GetIndex(item.I, item.J, item.K));

                Drain drain = new Drain(item.I, item.J, item.K, mf.GridData.RowsCount, mf.GridData.ColsCount, mf.GridData.LayersCount, mf.StressPeriods.InnerList.Count);

                if (owner is PointFO)
                {
                    this.assistMapToModFlow(stressPeriods, drain.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, drain.Elevation, _multiElevation);

                    //for (int i = 0; i < this.NPeriods; i++)
                    //{

                    //    drain.Conductance[i] = this._multiConductance[i];

                    //    drain.Elevation[i]=this._multiElevation[i];
                    //}
                    

                    //drain.FirstConductance = this.FirstConductance;
                    //drain.FirstElevation = this.Elevation;
                    

                }

                if (owner is LineFO)
                {
                    List<double> starts = new List<double>(stressPeriods.Count);
                    List<double> ends = new List<double>(stressPeriods.Count);

                    foreach (var sp in stressPeriods)
                    {
                        starts.Add(0);
                        ends.Add(0);
                    }

                    this.assistMapToModFlow(stressPeriods, starts, _multiStartElevation);
                    this.assistMapToModFlow(stressPeriods, ends, _multiEndElevation);
                    this.assistMapToModFlow(stressPeriods, drain.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, drain.Elevation, _multiElevation);

                    for (int i = 0; i < stressPeriods.Count; i++)
                    {
                        drain.Conductance[i] *= item.Value;
                        drain.Elevation[i] = starts[i] + (ends[i] - starts[i]) * (item.LineCurrentTotalLength / TotalValue);
                    }



                    //for (int i = 0; i < this.NPeriods;i++ )
                    //{
                    //    drain.Conductance[i] = this._multiConductance[i] * item.Value;
                    //    drain.Elevation[i] = this._multiStartElevation[i] + (this._multiEndElevation[i] - this._multiStartElevation[i]) * (item.LineCurrentTotalLength / TotalValue);

                    //}
                    //currentLength += item.Value;
                }

                if (owner is PolygonFO)
                {
                    this.assistMapToModFlow(stressPeriods, drain.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, drain.Elevation, _multiElevation);

                    for (int i = 0; i < stressPeriods.Count; i++)
                    {
                        drain.Conductance[i] *= item.Value;
                    }

                    //for (int i = 0; i < this.NPeriods; i++)
                    //{
                    //    drain.Conductance[i] = this._multiConductance[i] * item.Value;
                    //    drain.Elevation[i] = this._multiElevation[i];
                    //}
                }
             



                Drains.Add(drain);

            }

            //mf.SourceSinks.Drains.UpdateDrains(Drains, indice);    
            mf.SourceSinks.Drains.AddTempDrains(Drains);
        }



      
    }
}
